#include "stdafx.h"
#include "SocketEvent.h"
#include "WindowsUtility.h"

namespace RoomFW {

SocketEvent::SocketEvent(SimpleSocket::SocketPtr socket) :
	socket_(socket),
	event_(),
	initialized_(false)
{
}

SocketEvent::~SocketEvent()
{
	if (initialized_)
	{
		int ret = SOCKET_ERROR;
		try {	// in case the socket is closed already remotely
			ret = ::WSAEventSelect(*socket_, event_, 0);
		} catch (...) 
		{
			G_LOG_0_WARNING("SocketEvent::~SocketEvent(): ::WSAEventSelect() return SOCKET_ERROR");
		}
	}
}

bool SocketEvent::initialize(long events)
{
	bool retVal = false;
	if (!initialized_ && socket_->valid())
	{
		// Create the event and associate to socket.
		if (event_.create(false, false)) // auto reset, initially unsignaled.
		{
			int ret = ::WSAEventSelect(*socket_, event_, events);
			SHOW_SOCKET_ERROR((SOCKET_ERROR != ret), "SocketEvent::initialize", "::WSAEventSelect");
			if (SOCKET_ERROR != ret)
			{
				initialized_ = true;
				retVal = true;
			}
		}
	}
	return retVal;
}

SimpleSocket::SocketPtr SocketEvent::getSocketPtr(void) const
{
	return socket_;
}

HANDLE SocketEvent::getEventHandle(void) const
{
	return event_;
}

bool SocketEvent::enumNetworkEvents(WSANETWORKEVENTS& networkEvents) const
{
	int ret = ::WSAEnumNetworkEvents(*socket_, event_, &networkEvents);
	SHOW_SOCKET_ERROR((SOCKET_ERROR != ret), "SocketEvent::enumNetworkEvents", "::WSAEnumNetworkEvents");
	return (SOCKET_ERROR != ret);
}

}
